package org.easier.framework.beancopier;

/**
 * 类拷贝器
 */
public class Beancopier {

    private volatile static CopierAdapter adapter;

    /**
     * 使用可自定义Mapper实现类
     * 且初始化一次即可
     *
     * @param agent
     */
    public static void init(CopierAdapter agent) {
        if (agent == null) {
            throw new RuntimeException("Beancopier not init");
        } else {
            Beancopier.adapter = agent;
        }
    }

    /**
     * 创建类拷入源对象的属性
     *
     * @param sourceObject
     * @param destinationObjectClass
     * @param <SourceObject>
     * @param <DestinationObject>
     * @return
     */
    public static <SourceObject, DestinationObject> DestinationObject mapper(SourceObject sourceObject, Class<DestinationObject> destinationObjectClass) {
        return mapper(sourceObject, destinationObjectClass, null);
    }

    /**
     * 创建类拷入源对象的属性
     * 并且给类型不匹配字段放入转换函数
     *
     * <pre>
     *    UserDTO dest = Beancopier.mapper(user, UserDTO.class, p -> {
     *             p.setLocalDateTime(LocalDateTimeUtil.to(user.getLocalDateTime()));
     *         });
     * </pre>
     *
     * @param sourceObject
     * @param destinationObjectClass
     * @param action
     * @param <SourceObject>
     * @param <DestinationObject>
     * @return
     */
    public static <SourceObject, DestinationObject> DestinationObject mapper(SourceObject sourceObject, Class<DestinationObject> destinationObjectClass, Action<DestinationObject> action) {
        if (adapter == null)
            throw new RuntimeException("没有为mapper指定实现");

        DestinationObject valObject = mapper(sourceObject, destinationObjectClass);
        if (action != null) {
            action.run(valObject);
        }
        return valObject;
    }

    /**
     * 对象间拷贝
     *
     * @param sourceObject
     * @param destinationObject
     * @param <SourceObject>
     * @param <DestinationObject>
     * @return
     */
    public static <SourceObject, DestinationObject> DestinationObject mapperObject(SourceObject sourceObject, DestinationObject destinationObject) {
        return mapperObject(sourceObject, destinationObject, null);
    }

    /**
     * 对象间拷贝
     * 并且给类型不匹配字段放入转换函数
     *
     * <pre>
     *     UserDTO dest = Beancopier.mapper(user, userDTO, p -> {
     *             p.setLocalDateTime(LocalDateTimeUtil.to(user.getLocalDateTime()));
     *         });
     * </pre>
     *
     * @param sourceObject
     * @param destinationObject
     * @param action
     * @param <SourceObject>
     * @param <DestinationObject>
     * @return
     */
    public static <SourceObject, DestinationObject> DestinationObject mapperObject(SourceObject sourceObject, DestinationObject destinationObject, Action<DestinationObject> action) {
        if (adapter == null)
            throw new RuntimeException("没有为mapper指定实现");
        DestinationObject valObject = mapperObject(sourceObject, destinationObject);

        if (action != null) {
            action.run(valObject);
        }
        return valObject;
    }
}
